package com.module.imagelib.glide.ui;

import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.util.AttributeSet;

import com.bumptech.glide.Glide;
import com.bumptech.glide.Priority;
import com.bumptech.glide.RequestBuilder;
import com.bumptech.glide.load.DataSource;
import com.bumptech.glide.load.engine.DiskCacheStrategy;
import com.bumptech.glide.load.engine.GlideException;
import com.bumptech.glide.load.resource.drawable.DrawableTransitionOptions;
import com.bumptech.glide.request.RequestListener;
import com.bumptech.glide.request.RequestOptions;
import com.bumptech.glide.request.target.SimpleTarget;
import com.bumptech.glide.request.target.Target;
import com.bumptech.glide.request.transition.Transition;
import com.module.imagelib.R;
import com.module.imagelib.glide.GlideApp;
import com.module.imagelib.glide.progress.OnImageListener;
import com.module.imagelib.glide.progress.OnProgressListener;
import com.module.imagelib.glide.progress.ProgressManager;
import com.module.imagelib.glide.utils.ImageFileUtils;

import java.io.File;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import jp.wasabeef.glide.transformations.CropCircleTransformation;
import jp.wasabeef.glide.transformations.CropSquareTransformation;
import jp.wasabeef.glide.transformations.RoundedCornersTransformation;

/**
 * 坑一：同时设置override（10, 10）与view宽高会导致图片模糊
 * 参考：https://www.cnblogs.com/guilin-hu/p/5706916.html
 * 参考：http://www.jcodecraeer.com/a/anzhuokaifa/2017/0928/8567.html
 * 参考：https://blog.csdn.net/Li_Qing_Xue/article/details/78919499
 * 封装的：https://github.com/androidstarjack/MyGlideFactoryView
 * 4.0使用：https://blog.csdn.net/u013005791/article/details/74532091#6-transformations
 * Created by dell on 2018/6/20
 */

public class GlideView extends androidx.appcompat.widget.AppCompatImageView {

    RequestOptions option;
    RequestBuilder mRequestBuilder;

    public GlideView(Context context) {
        super(context);
        init();
    }

    public GlideView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }


    private void init() {
//        override会自适应实际显示图片宽高（默认图与下载图大小不一样，会显示有大小）
//        centerCrop 中心剪切-放大图片填充满宽高剪切多余部分（优先满足override宽高然后拉伸至view设置到宽高-所以同时设置可能会导致图片模糊）
//        fitCenter 固定中心-缩小图片到全部显示其余留白
//        circleCrop 圆形剪切-放大图片取宽高最小值剪切多余部分
//        centerInside 效果同fitCenter
//        1.不设默认图：成功：按原图比例返回（根据屏幕宽高缩放取图片最长，多余部分留白）失败：返回0-0
//        2.不设默认图，设置override：成功：按原图比例返回（根据override宽高缩放取图片最长，多余部分自适应） 失败：返回0-0
//        3.不设默认图，设置view宽高：成功：按原图比例返回（根据view宽高缩放取图片最长，多余部分留白）失败：返回200-200
//        4.不设默认图，设置centerCrop（需要设置override或者view宽高）：成功：按override或view宽高返回（根据override或view宽高缩放取图片最短，多余图片裁剪） 失败返回0-0
//        5.不设默认图，设置fitCenter 同默认
//        6.不设默认图，设置centerInside 同默认
//        7.不设默认图，设置circleCrop（需要设置override或者view宽高）：成功：按override或view宽高返回（根据override或view宽高缩放取图片最短，多余图片裁剪，根据图片中心画圆多余部分留白） 失败返回0-0
//        8.不设默认图，设置GlideRoundTransform 同circleCrop
//        9.设置placeholder：重复1~8。失败：除非设置view宽高，否则都会返回默认图大小
//        10.设置error：效果同不设默认图
        option = new RequestOptions()
//                .apply(RequestOptions.bitmapTransform(new BlurTransformation(25,3)))
                //等待时的图片
                .placeholder(R.mipmap.ic_launcher)
                //加载图片失败（不设会使用placeholder的图片）
//                .error(R.mipmap.ic_launcher)
                //硬盘缓存策略
//                DiskCacheStrategy.ALL 使用DATA和RESOURCE缓存远程数据，仅使用RESOURCE来缓存本地数据。
//                DiskCacheStrategy.NONE 不使用磁盘缓存
//                DiskCacheStrategy.DATA 在资源解码前就将原始数据写入磁盘缓存
//                DiskCacheStrategy.RESOURCE 在资源解码后将数据写入磁盘缓存，即经过缩放等转换后的图片资源。
//                DiskCacheStrategy.AUTOMATIC 根据原始图片数据和资源编码策略来自动选择磁盘缓存策略。
                .diskCacheStrategy(DiskCacheStrategy.NONE)
                //跳过内存缓存
                .skipMemoryCache(true)
                //不使用动画
                .dontAnimate();
    }

    public void loadImage(String url) {
        GlideApp.with(this.getContext()).load(url).override(500, 300).into(this);
    }

    /**
     * 第一步设置url
     */
    public GlideView url(String url) {
        mRequestBuilder = GlideApp.with(this.getContext().getApplicationContext()).load(url).apply(option);
        return this;
    }

    public GlideView asGif(String url) {
        mRequestBuilder = GlideApp.with(this).load(url);
        return this;
    }

    public GlideView asBitmap(String url) {
        mRequestBuilder = GlideApp.with(this).asBitmap().load(url);
        return this;
    }

    /**
     * ---默认图---
     */

    public GlideView placeholder(int resId) {
        mRequestBuilder.placeholder(resId);
        return this;
    }

    public GlideView error(int resId) {
        mRequestBuilder.error(resId);
        return this;
    }

    /** ---图片的大小--- */

    /**
     * 设置下载后的图片大小
     */
    public GlideView size(int width, int height) {
        mRequestBuilder.override(width, height);
        return this;
    }

    /**
     * 设置view大小
     */
    public GlideView params(int width, int height) {
        getLayoutParams().width = width;
        getLayoutParams().height = height;
        return this;
    }

    /** ---图片的样式--- */

    /**
     * 设置图片圆角
     */
    public GlideView round(int radius) {
        mRequestBuilder.transform(new RoundedCornersTransformation(radius, 0)); //第三方的
//        mRequestBuilder.transform(new RoundedCorners(radius)); //系统的
//        mRequestBuilder.transform(new GlideRoundTransform(radius)); //自定义的
        return this;
    }

    /**
     * 设置图片圆形
     */
    public GlideView circle() {
        mRequestBuilder.transform(new CropCircleTransformation());
//        mRequestBuilder.transform(new CircleCrop());
//        mRequestBuilder.transform(new GlideCircleTransform());
        return this;
    }

    /**
     * 设置图片矩形
     */
    public GlideView square() {
        mRequestBuilder.transform(new CropSquareTransformation());
//        mRequestBuilder.transform(new CenterCrop());
//        mRequestBuilder.transform(new GlideNormalTransform());
        return this;
    }

    /** ---图片的缩放--- */

    /**
     * centerCrop是利用图片图填充ImageView设置的大小，如果ImageView的Height是match_parent则图片就会被拉伸填充
     * 也可以设置view的scaleType/centerCrop
     */
    public GlideView centerCrop() {
        mRequestBuilder.centerCrop();
        return this;
    }

    /**
     * fitCenter即缩放图像让图像都测量出来等于或小于 ImageView 的边界范围,该图像将会完全显示，但可能不会填满整个
     * 也可以设置view的scaleType/fitCenter
     */
    public GlideView fitCenter() {
        mRequestBuilder.fitCenter();
        return this;
    }

    /** ---过渡动画--- */

    /**
     * 淡入淡出
     */
    public GlideView crossFade() {
        mRequestBuilder.transition(DrawableTransitionOptions.withCrossFade());
        return this;
    }

    /**
     * 加载进度条
     */
    public GlideView progress(final OnImageListener onImageListener) {
        final OnProgressListener internalProgressListener = new OnProgressListener() {
            @Override
            public void onProgress(String imageUrl, long bytesRead, long totalBytes, boolean isDone, GlideException exception) {
                int percent = (int) ((bytesRead * 1.0f / totalBytes) * 100.0f);
                onImageListener.onProgress(percent, isDone, exception);
            }
        };
        ProgressManager.addProgressListener(internalProgressListener);
        mRequestBuilder = mRequestBuilder.listener(new RequestListener() {
            @Override
            public boolean onLoadFailed(@Nullable GlideException e, Object model, Target target, boolean isFirstResource) {
                onImageListener.onProgress(0, true, e);
                ProgressManager.removeProgressListener(internalProgressListener);
                return false;
            }

            @Override
            public boolean onResourceReady(Object resource, Object model, Target target, DataSource dataSource, boolean isFirstResource) {
                onImageListener.onProgress(100, true, null);
                ProgressManager.removeProgressListener(internalProgressListener);
                return false;
            }
        });
        return this;
    }

    /**
     * ---其他---
     */

    /**
     * 图片加载优先级
     * Priority.IMMEDIATE (立即)
     * Priority.HIGH    (高)
     * Priority.NORMAL  (中)
     * Priority.LOW （低)
     */
    public GlideView priority(Priority priority) {
        mRequestBuilder.priority(priority);
        return this;
    }

    /**
     * 当列表在滑动的时候，调用pauseRequests()取消请求，滑动停止时，调用resumeRequests()恢复请求
     */
    public void resumeRequests() {
        Glide.with(this).resumeRequests();
    }

    /**
     * 当列表在滑动的时候，调用pauseRequests()取消请求，滑动停止时，调用resumeRequests()恢复请求
     */
    public void pauseRequests() {
        GlideApp.with(this).pauseRequests();
    }

    /**
     * 清除内存缓存
     * 主线程调用
     */
    public void clearMemory() {
        final Activity act = (Activity) this.getContext();
        act.runOnUiThread(new Runnable() {
            @Override
            public void run() {
                GlideApp.get(act).clearMemory();
            }
        });
    }

    /**
     * 清除硬盘缓存
     * 子线程中调用
     */
    public void clearDiskCache() {
        final Activity act = (Activity) this.getContext();
        new Thread(new Runnable() {
            @Override
            public void run() {
                GlideApp.get(act).clearDiskCache();
            }
        }).start();
    }


    /**
     * 开始加载
     */
    public void load() {
        mRequestBuilder.into(this);
    }

    /**
     * 开始保存
     */
    public void target(SimpleTarget<Bitmap> simpleTarget) {
        mRequestBuilder.into(simpleTarget);

    }

    /**
     * 下载原文件
     */
    public void download(String url) {
        GlideApp.with(this.getContext()).download(url).into(new SimpleTarget<File>() {
            @Override
            public void onResourceReady(@NonNull final File resource, @Nullable Transition<? super File> transition) {
                // /data/user/0/com.dengqi.mymodule/cache/image_manager_disk_cache/b4c6b32304cb156e554f6c541520173d8870e7f1e8c97017f0a68f87da80106b.0
                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        ImageFileUtils.copyFile(resource);
                    }
                }).start();
            }
        });
    }


}
